// scores 是 int[] IEnumerable<int> highScoresQuery = from score in scores where score > 80 orderby score descending select score;
将序列转换为新类型的对象
IEnumerable<string> highScoresQuery2 = from score in scores where score > 80 orderby score descending select$"The score is {score}";
检索有关源数据的单独值
int highScoreCount = (from score in scores where score > 80 select score) .Count();
查询表达式是什么
查询表达式是以查询语法表示的查询。
规则
查询表达式必须以 from 子句开头,且必须以 select 或 group 子句结尾。 在第一个 from 子句与最后一个 select 或 group 子句之间,可以包含以下这些可选子句中的一个或多个: where、orderby、join、let 甚至是其他 from 子句。 还可以使用 into 关键字,使 join 或 group 子句的结果可以充当相同查询表达式中的其他查询子句的源。
查询变量
在 LINQ 中,查询变量是存储查询而不是查询结果的任何变量。
// Query Expression. IEnumerable<int> scoreQuery = //query variable from score in scores //required where score > 80// optional orderby score descending// optional select score; //must end with select or group
上面的示例中,scoreQuery 是查询变量,它有时仅仅称为查询。
查询变量可以存储采用查询语法、方法语法或是两者的组合进行表示的查询。
//Query syntax IEnumerable<City> queryMajorCities = from city in cities where city.Population > 100000 select city;
// Here var is required because the query // produces an anonymous type. var queryNameAndPop = from country in countries selectnew { Name = country.Name, Pop = country.Population };
使用 into 进行延续
可以在 select 或 group 子句中使用 into 关键字创建存储查询的临时标识符。
// percentileQuery is an IEnumerable<IGrouping<int, Country>> var percentileQuery = from country in countries let percentile = (int) country.Population / 10_000_000 group country by percentile into countryGroup where countryGroup.Key >= 20 orderby countryGroup.Key select countryGroup;
筛选、排序和联接
在开头 from 子句与结尾 select 或 group 子句之间,所有其他子句(where、join、orderby、from、let)都是可选的。任何可选子句都可以在查询正文中使用零次或多次。
where 子句
使用 where 子句可基于一个或多个谓词表达式,从源数据中筛选出元素。
IEnumerable<City> queryCityPop = from city in cities where city.Population < 200000 && city.Population > 100000 select city;
orderby 子句
使用 orderby 子句可按升序或降序对结果进行排序。还可以指定次要排序顺序。
IEnumerable<Country> querySortedCountries = from country in countries orderby country.Area, country.Population descending select country;
注意: ascending 关键字是可选的,如果未指定任何顺序,则它是默认排序顺序。
join 子句
使用 join 子句可基于每个元素中指定的键之间的相等比较,将一个数据源中的元素与另一个数据源中的元素进行关联和/或合并。在 LINQ 中,联接操作是对元素属于不同类型的对象序列执行。联接了两个序列之后,必须使用 select 或 group 语句指定要存储在输出序列中的元素,还可以使用匿名类型将每组关联元素中的属性合并到输出序列的新类型中。
var categoryQuery = from cat in categories join prod in products on cat equals prod.Category selectnew { Category = cat, Name = prod.Name };
还可以通过使用 into 关键字将 join 操作的结果存储到临时变量中来执行分组联接。
let 子句
使用 let 子句可将表达式(如方法调用)的结果存储在新范围变量中。
string[] names = { "Svetlana Omelchenko", "Claire O'Donnell", "Sven Mortensen", "Cesar Garcia" }; IEnumerable<string> queryFirstNames = from name in names let firstName = name.Split(' ')[0] select firstName;
查询表达式中的子查询
查询子句本身可能包含查询表达式,这有时称为子查询。每个子查询都以自己的 from 子句开头,该子句不一定指向第一个 from 子句中的相同数据源。
var queryGroupMax = from student in students group student by student.GradeLevel into studentGroup selectnew { Level = studentGroup.Key, HighestScore = (from student2 in studentGroup select student2.Scores.Average()) .Max() };